package ar.fiuba.logger.reporter;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import ar.fiuba.logger.LogFormatterInterface;
import ar.fiuba.logger.LogMessageInterface;
import ar.fiuba.logger.LogReporter;

/**
 * The Class FileReporter.
 * 
 * This class implements the file reporter. The file reporter output log messages to a given file.
 */
public class FileReporter implements LogReporter {

  /** The filename. */
  private String filename;

  /** The formatter. */
  private LogFormatterInterface formatter;

  /** The writer. */
  private PrintWriter writer;

  /**
   * Instantiates a new file reporter.
   *
   * @param filename the filename
   * @param formatter the formatter
   * @throws FileNotFoundException the file not found exception
   * @throws UnsupportedEncodingException the unsupported encoding exception
   */
  public FileReporter(String filename, LogFormatterInterface formatter)
      throws FileNotFoundException, UnsupportedEncodingException {
    init(filename, formatter, "UTF-8");
  }

  /**
   * Instantiates a new file reporter.
   *
   * @param filename the filename
   * @param formatter the formatter
   * @param encoding the encoding
   * @throws FileNotFoundException the file not found exception
   * @throws UnsupportedEncodingException the unsupported encoding exception
   */
  public FileReporter(String filename, LogFormatterInterface formatter, String encoding)
      throws FileNotFoundException, UnsupportedEncodingException {
    init(filename, formatter, encoding);
  }

  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    FileReporter other = (FileReporter) obj;
    if (filename == null) {
      if (other.filename != null)
        return false;
    } else if (!filename.equals(other.filename))
      return false;
    return true;
  }

  /**
   * Method called upon object destruction. It is called by the garbage collector and releases the
   * file.
   * 
   */
  protected void finalize() {
    writer.close();
  }

  /* (non-Javadoc)
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((filename == null) ? 0 : filename.hashCode());
    return result;
  }

  /**
   * Initialize the FileReporter.
   *
   * @param filename the filename
   * @param formatter the formatter
   * @param encoding the encoding
   * @throws FileNotFoundException the file not found exception
   * @throws UnsupportedEncodingException the unsupported encoding exception
   */
  private void init(String filename, LogFormatterInterface formatter, String encoding)
      throws FileNotFoundException, UnsupportedEncodingException {
    this.filename = filename;

    this.writer = new PrintWriter(filename, encoding);

    this.formatter = formatter;
  }

  /*
   * (non-Javadoc)
   * 
   * @see fiuba.logger.reporter.Reporter#report(java.lang.String)
   */
  public void report(LogMessageInterface message) {
    writer.println(formatter.format(message));
    writer.flush();
  }
}
